package com.hzncc.flowable_diboot.job;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.diboot.core.holder.ThreadLocalHolder;
import com.diboot.core.util.BeanUtils;
import com.diboot.core.util.JSON;
import com.diboot.core.util.S;
import com.diboot.core.vo.JsonResult;
import com.diboot.tenant.entity.IamTenant;
import com.diboot.tenant.service.IamTenantService;
import com.hzncc.flowable_diboot.entity.*;
import com.hzncc.flowable_diboot.service.*;
import com.hzncc.flowable_diboot.service.impl.TianYanChaService;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;

import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

@Service
@RequiredArgsConstructor
@Slf4j
public class SapDataSyncService {
    private final IamTenantService iamTenantService;

    private final SapCustomerService sapCustomerService;

    private final SalesGroupContentService salesGroupContentService;

    private final TianYanChaService tianYanChaService;

    private final CustomerService customerService;

    private final Kna1XService kna1XService;

    private final KnbkService knbkService;

    private final CustomerPortraitService customerPortraitService;

    /**
     * 同步sap客户数据
     *
     * @author 陈广煜
     * @date 2024/7/18
     */
    public void syncData() {
        QueryWrapper<Kna1X> qw = new QueryWrapper<>();
        qw.lambda().eq(Kna1X::getCrmflaggw, "1");
        // crm 未同步的数据
        List<Kna1X> list = kna1XService.list(qw);
        QueryWrapper<Knbk> wrapper = new QueryWrapper<>();
        wrapper.lambda().eq(Knbk::getCrmflaggw, "1");
        List<Knbk> knbks = knbkService.list(wrapper);
        List<IamTenant> iamTenants = iamTenantService.getEntityList(new QueryWrapper<>());
        Map<String, String> salesOrgTenant = new HashMap<>();
        for (IamTenant iamTenant : iamTenants) {
            salesOrgTenant.put(iamTenant.getOrgId(), iamTenant.getId());
        }
        List<Kna1X> successList = new ArrayList<>();
        List<SalesGroupContent> salesGroups = new ArrayList<>();
        Map<String, SapCustomer> customerMap = new HashMap<>();
        for (Kna1X kna1X : list) {
            String tenantId = salesOrgTenant.get(kna1X.getVkorg());
            if (tenantId == null) {
                log.error("{}未找到销售组织对应的租户", kna1X.getKunnr());
                continue;
            }
            SapCustomer sapCustomer = convertCustomer(kna1X);
            customerMap.put(sapCustomer.getSapNo() + tenantId, sapCustomer);
            sapCustomer.setTenantId(tenantId);
            SalesGroupContent salesGroupContent = convertSalesGroupContent(kna1X);
            salesGroupContent.setTenantId(tenantId);
            salesGroups.add(salesGroupContent);
            successList.add(kna1X);
        }
        Collection<SapCustomer> cus = customerMap.values();
        // 同步sap客户
        List<SapCustomer> sapCustomers = validateCustomer(cus);
        setBankInfo(sapCustomers, knbks);
        for (SalesGroupContent salesGroup : salesGroups) {
            SapCustomer sapCustomer = customerMap.get(salesGroup.getSapNo() + salesGroup.getTenantId());
            String salesOrg = sapCustomer.getSalesOrg();
            sapCustomer.setSalesOrg(salesOrg == null ? salesGroup.getSalesGroup() : salesOrg + "," + salesGroup.getSalesGroup());
            sapCustomer.setPriceProcess("1"); // 定价过程 默认为 ‘1’
        }
        sapCustomerService.createEntities(sapCustomers);
        for (SalesGroupContent salesGroup : salesGroups) {
            SapCustomer sapCustomer = customerMap.get(salesGroup.getSapNo() + salesGroup.getTenantId());
            salesGroup.setSapCustomerId(sapCustomer.getId());
            String salesOrg = sapCustomer.getSalesOrg();
            sapCustomer.setSalesOrg(salesOrg == null ? salesGroup.getSalesGroup() : salesOrg + "," + salesGroup.getSalesGroup());
        }
        sapCustomerService.updateEntities(sapCustomers);
        salesGroupContentService.createEntities(salesGroups);
        // 创建crm客户
//        createCrmCustomer(sapCustomers);
        // 回写flag
        successList.forEach(e -> e.setCrmflaggw("0"));
        kna1XService.updateBatchByMultiId(successList);
        knbks.forEach(e -> e.setCrmflaggw("0"));
        knbkService.updateBatchByMultiId(knbks);
        log.info("同步完成，本次同步{}条数据", successList.size());
    }

    /**
     * 创建CRM客户
     *
     * @param cus sap客户
     * @author 陈广煜
     * @date 2024/7/4
     */
    private void createCrmCustomer(Collection<SapCustomer> cus) {
        List<Customer> customers = new ArrayList<>();
        for (SapCustomer sapCustomer : cus) {
            Customer customer = new Customer();
            customer.setName(sapCustomer.getName());
            customer.setTenantId(sapCustomer.getTenantId());
            customer.setIsEnter(0);
            customer.setTaxNumber(sapCustomer.getTax());
            customer.setEnterDays(0L);
            customer.setEnterTime(LocalDateTime.now());
//            customer.setEnterReason("sap客户同步");
            customer.setBusiness(sapCustomer.getBusiness());
//            customer.setSource("sap");
            customer.setSn(sapCustomer.getSapNo());
            JsonResult<?> detail = tianYanChaService.detail(sapCustomer.getName());
            if (detail.getCode() != 0) {
                continue;
            }
            Map<String, String> data = (Map<String, String>) detail.getData();
            customer.setCreditCode(data.get("creditCode"));
            customer.setAddress(data.get("regLocation"));
            customer.setTaxNumber(data.get("taxNumber"));
            customer.setCity(data.get("city"));
            customers.add(customer);
        }
        customerService.createEntities(customers);
        List<CustomerPortrait> portraits = new ArrayList<>();
        for (Customer customer : customers) {
            CustomerPortrait customerPortrait = new CustomerPortrait();
            customerPortrait.setCustomerId(customer.getId());
            customerPortrait.setTenantId(customer.getTenantId());
            portraits.add(customerPortrait);

        }
        customerPortraitService.createEntities(portraits);
    }

    private SapCustomer convertCustomer(Kna1X kna1X) {
        String jsonStr = JSON.stringify(kna1X);
        return JSON.parseObject(jsonStr, SapCustomer.class);
    }

    private SalesGroupContent convertSalesGroupContent(Kna1X kna1X) {
        String jsonStr = JSON.stringify(kna1X);
        SalesGroupContent salesGroupContent = JSON.parseObject(jsonStr, SalesGroupContent.class);
        salesGroupContent.setIsFreeze(S.equals(kna1X.getLoevm(), "X") ? "1" : "0");
        return salesGroupContent;
    }

    /**
     * 数据校验
     * <p>
     * 该方法用于校验给定的SapCustomer集合中是否存在重复的客户信息
     * 它通过查询数据库中已存在的客户信息，来过滤掉重复的条目
     *
     * @param sapCustomers 一个SapCustomer对象的集合，代表待校验的客户信息
     * @return 返回一个List<SapCustomer>对象，包含校验后无重复的SapCustomer对象
     * @author 陈广煜
     * @date 2024/7/5
     */
    private List<SapCustomer> validateCustomer(Collection<SapCustomer> sapCustomers) {
        // 将输入的SapCustomer集合按租户ID分组，以便后续处理
        Map<String, List<SapCustomer>> groupByTenant = sapCustomers.stream().collect(Collectors.groupingBy(SapCustomer::getTenantId));
        // 创建一个HashSet用于存储最终判定为重复的客户信息
        Set<String> set = new HashSet<>();
        // 遍历每个租户的SapCustomer列表
        for (Map.Entry<String, List<SapCustomer>> entry : groupByTenant.entrySet()) {
            List<SapCustomer> value = entry.getValue();
            // 提取当前租户下所有客户的SapNo
            List<String> no = BeanUtils.collectToList(value, SapCustomer::getSapNo);
            // 创建一个QueryWrapper对象，用于构建查询条件
            QueryWrapper<SapCustomer> qw = new QueryWrapper<>();
            qw.lambda().in(SapCustomer::getSapNo, no);
            // 设置ThreadLocal以忽略某些拦截器的影响
            ThreadLocalHolder.setIgnoreInterceptor();
            // 查询数据库中已存在的客户信息
            List<SapCustomer> exist = sapCustomerService.getEntityList(qw);
            // 将查询到的已存在客户信息转换为一个Set，用于快速查找
            Set<String> collect = exist.stream().map(e -> e.getSapNo() + e.getTenantId()).collect(Collectors.toSet());
            // 如果存在重复的客户信息，则将其添加到重复集合中
            if (collect.size() > 0) {
                set.addAll(collect);
            }
        }
        // 过滤掉重复的客户信息，返回无重复的SapCustomer列表
        return sapCustomers.stream().filter(e -> !set.contains(e.getSapNo() + e.getTenantId())).collect(Collectors.toList());
    }

    /**
     * 同步银行账户信息
     *
     * @param sapCustomers
     * @param knbks
     * @author 陈广煜
     * @date 2024/7/18
     */
    private void setBankInfo(List<SapCustomer> sapCustomers, List<Knbk> knbks) {
        Map<String, List<Knbk>> map = knbks.stream().collect(Collectors.groupingBy(Knbk::getKunnr));
        for (SapCustomer sapCustomer : sapCustomers) {
            List<Knbk> elements = map.get(sapCustomer.getSapNo());
            if (elements != null) {
                Knbk knbk = elements.get(0);
                sapCustomer.setOpeningBank(knbk.getBankn());
                sapCustomer.setAccount(knbk.getBanka());
                sapCustomer.setAccountName(knbk.getKoinh());
            }
        }
    }

    public void initSap() {
        QueryWrapper<Kna1X> qw = new QueryWrapper<>();
//        qw.lambda().eq(Kna1X::getCrmflaggw, "1");
        // crm 未同步的数据
        List<Kna1X> list = kna1XService.list(qw);
        QueryWrapper<Knbk> wrapper = new QueryWrapper<>();
//        wrapper.lambda().eq(Knbk::getCrmflaggw, "1");
        List<Knbk> knbks = knbkService.list(wrapper);
        List<IamTenant> iamTenants = iamTenantService.getEntityList(new QueryWrapper<>());
//        Map<String, List<IamTenant>> tenantMap = new HashMap<>();
//        for (IamTenant iamTenant : iamTenants) {
//            String oaNum = iamTenant.getOaNum(); // 公司代码
//            String orgId = iamTenant.getOrgId(); // 销售组织
//            if (S.isBlank(orgId)) {
//                continue;
//            }
//            List<String> orgs = S.splitToList(orgId); // 多个销售组织用‘,’分割
//            // 按公司代码-销售组织分组租户
//            for (String org : orgs) {
//                String key = oaNum + "-" + org;
//                List<IamTenant> tenants = tenantMap.get(key) == null ? new ArrayList<>() : tenantMap.get(key);
//                tenants.add(iamTenant);
//                tenantMap.put(key, tenants);
//            }
//        }
        Map<String, String> salesOrgTenant = new HashMap<>();
        for (IamTenant iamTenant : iamTenants) {
            salesOrgTenant.put(iamTenant.getOrgId(), iamTenant.getId());
        }
        List<Kna1X> successList = new ArrayList<>();
        List<SalesGroupContent> salesGroups = new ArrayList<>();
        Map<String, SapCustomer> customerMap = new HashMap<>();
        for (Kna1X kna1X : list) {
//            List<IamTenant> tenants = tenantMap.get(kna1X.getBukrs() + "-" + kna1X.getVkorg());
//            if (tenants == null) {
//                continue;
//            }
            String tenantId = salesOrgTenant.get(kna1X.getVkorg());
            if (tenantId == null) {
                log.error("{}未找到销售组织对应的租户", kna1X.getKunnr());
                continue;
            }
//            for (IamTenant tenant : tenants) {
            SapCustomer sapCustomer = convertCustomer(kna1X);
            customerMap.put(sapCustomer.getSapNo() + tenantId, sapCustomer);
            sapCustomer.setTenantId(tenantId);
            SalesGroupContent salesGroupContent = convertSalesGroupContent(kna1X);
            salesGroupContent.setTenantId(tenantId);
            salesGroups.add(salesGroupContent);
//            }
            successList.add(kna1X);
        }
        Collection<SapCustomer> cus = customerMap.values();
        // 同步sap客户
        List<SapCustomer> sapCustomers = validateCustomer(cus);
        setBankInfo(sapCustomers, knbks);
        for (SalesGroupContent salesGroup : salesGroups) {
            SapCustomer sapCustomer = customerMap.get(salesGroup.getSapNo() + salesGroup.getTenantId());
            String salesOrg = sapCustomer.getSalesOrg();
            sapCustomer.setSalesOrg(salesOrg == null ? salesGroup.getSalesGroup() : salesOrg + "," + salesGroup.getSalesGroup());
            sapCustomer.setPriceProcess("1"); // 定价过程 默认为 ‘1’
        }
        sapCustomerService.createEntities(sapCustomers);
        for (SalesGroupContent salesGroup : salesGroups) {
            SapCustomer sapCustomer = customerMap.get(salesGroup.getSapNo() + salesGroup.getTenantId());
            salesGroup.setSapCustomerId(sapCustomer.getId());
        }
//        sapCustomerService.updateEntities(sapCustomers);
        salesGroupContentService.createEntities(salesGroups);
        // 创建crm客户
//        createCrmCustomer(sapCustomers);
        // 回写flag
//        successList.forEach(e -> e.setCrmflaggw("0"));
//        kna1XService.updateBatchByMultiId(successList);
//        knbks.forEach(e -> e.setCrmflaggw("0"));
//        knbkService.updateBatchByMultiId(knbks);
        log.info("同步完成，本次同步{}条数据", successList.size());
    }
}
